package com.local.hwcard;

import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.Button;
import android.widget.Toast;
import android.app.AlertDialog;
import android.content.DialogInterface;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.content.pm.ActivityInfo;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import android.media.MediaPlayer;


public class MainActivity extends AppCompatActivity implements HWCardView.OnMoveListener {
    private static final String TAG = "MainActivity";
    private static final int PERMISSION_REQUEST_CODE = 1;
    private MediaPlayer mMediaPlayer; // 用于播放音频的MediaPlayer实例
    private int mCardValue;

    private Button giveupButton;
    private Button talkButton;
    private Button configButton;
    private HWCardView gameBoard;
    private VoiceService voiceService;
    private String lastDeviceId = "";

    private boolean isVoiceServiceBound = false;

    // 语音服务连接
    private ServiceConnection voiceServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "Voice service connected");
            VoiceService.LocalBinder binder = (VoiceService.LocalBinder) service;
            voiceService = binder.getService();
            isVoiceServiceBound = true;

            voiceService.setCallback(new VoiceService.Callback() {
                @Override
                public void onConnect(String message) {
                    String[] array = message.split(":");
                    if (array.length < 2) {
                        return;
                    }
                    String joinMessage = String.format("当前共有%s人", array[1]);
                    gameBoard.setWaitRoom(joinMessage, Integer.parseInt(array[1]));
                }

                @Override
                public void onOtherJoin(String message) {
                    String[] array = message.split(":");
                    if (array.length < 3) {
                        return;
                    }
                    String joinMessage = String.format("%s 加入房间，当前共有%s人",
                            DeviceInfor.getDisplayName(array[1]), array[2]);
                    gameBoard.addJoinMessage(joinMessage, Integer.parseInt(array[2]));
                }

                @Override
                public void onConnectFail(String errorMsg) {
                    Toast.makeText(MainActivity.this, "Connect failed: " + errorMsg, Toast.LENGTH_LONG).show();
                }

                @Override
                public void onInitGame(String message) {
                    String[] array = message.split(":");
                    if (array.length < 8) {
                        return;
                    }
                    gameBoard.resetGame(array);
                }

                @Override
                public void onAck(String message) {
                    String[] array = message.split(":");
                    if (array.length < 9) {
                        return;
                    }
                    gameBoard.ackPlay(array);
                }

                @Override
                public void onSync(String message) {
                    String[] array = message.split(":");
                    if (array.length < 5) {
                        return;
                    }
                    gameBoard.syncPlay(array);
                }

                @Override
                public void onGiveup(String message) {
                    String[] array = message.split(":");
                    if (array.length < 3) {
                        return;
                    }
                    gameBoard.giveupPlay(array);
                }

            });

            voiceService.connectToServer();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "Voice service disconnected");
            voiceService = null;
            isVoiceServiceBound = false;
        }
    };


    @Override
    public void onOutsizeFocus(int x) {

    }

    @Override
    public void onCardViewError(String message) {
        Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
    }

    @Override
    public void onSendMessage(String message) {
        if (!voiceService.sendMessage(message)) {
            try {
                Thread.sleep(30);
                voiceService.sendMessage(message);
            } catch (InterruptedException e) {
                Log.d(TAG, e.getMessage());
            }
        }
    }

    @Override
    public void onCardSound(int cardNum, int cardValue) {
        try {
            if (DeviceInfor.getCheck().equals("true")) {
                playSound(cardNum, cardValue);
            }
        } catch (Exception e) {
            Log.d(TAG, e.getMessage());
        }
    }

    private ActivityResultLauncher<Intent> configActivityLauncher = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            result -> {
                if (result.getResultCode() == RESULT_OK) {
                    if (!lastDeviceId.equals(DeviceInfor.getLocalID())) {
                        Log.d(TAG, "change local device id");
                        if (!gameBoard.getIsRoomStart()) {
                            unbindAndStopServices();
                            startAndBindServices();
                        }
                    }
                }
            }
    );

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate: Activity created ");
        setContentView(R.layout.activity_main);

        DeviceInfor.loadConfig(getApplicationContext());

        giveupButton = findViewById(R.id.giveupButton);
        talkButton = findViewById(R.id.talkButton);
        configButton = findViewById(R.id.configButton);
        gameBoard = findViewById(R.id.gameBoard);
        gameBoard.setOnMoveListener(this);

        checkPermissions();

        configButton.setOnClickListener(v -> {
                lastDeviceId = DeviceInfor.getLocalID();
                Intent intent = new Intent(MainActivity.this, ConfigActivity.class);
                configActivityLauncher.launch(intent);
            }
        );

        giveupButton.setOnClickListener(v -> {
            if (!gameBoard.getIsRoomStart()) {
                return;
            }

            // 创建对话框构建器
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("放弃");
            builder.setMessage("确定要放弃本局吗？");
            builder.setPositiveButton("是", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    onSendMessage("GIVEUP:" + DeviceInfor.getLocalID());
                    dialog.dismiss(); // 关闭对话框
                }
            });

            // 设置"No"按钮及点击事件
            builder.setNegativeButton("否", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss(); // 关闭对话框
                }
            });

            // 设置对话框不可通过点击外部关闭
            builder.setCancelable(false);
            AlertDialog dialog = builder.create();
            dialog.show();
        });

        talkButton.setOnTouchListener((v, event) -> {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    Log.d(TAG, "Talk button pressed: Starting recording");
                    voiceService.startRecording();
                    talkButton.setText("说话中..");
                    return true;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    Log.d(TAG, "Talk button released: Stopping recording");
                    voiceService.stopRecording();
                    talkButton.setText("按下说话");
                    return true;
            }
            return false;
        });

		startAndBindServices();
        gameBoard.requestFocus();
        gameBoard.requestFocusFromTouch();
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
    }

    private void startAndBindServices() {
        // 启动并绑定语音服务
        Intent voiceIntent = new Intent(this, VoiceService.class);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService(voiceIntent);
        } else {
            startService(voiceIntent);
        }
        bindService(voiceIntent, voiceServiceConnection, BIND_AUTO_CREATE);
    }

    private void unbindAndStopServices() {
        if (isVoiceServiceBound) {
            unbindService(voiceServiceConnection);
            isVoiceServiceBound = false;
        }        
        stopService(new Intent(this, VoiceService.class));
    }

    private void checkPermissions() {
        Log.d(TAG, "checkPermissions: Checking required permissions");
        String[] permissions = {
                android.Manifest.permission.RECORD_AUDIO,
                android.Manifest.permission.INTERNET,
                android.Manifest.permission.MODIFY_AUDIO_SETTINGS
        };

        boolean needPermission = false;
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(this, permission)
                    != PackageManager.PERMISSION_GRANTED) {
                needPermission = true;
                Log.w(TAG, "checkPermissions: Missing permission: " + permission);
            }
        }

        if (needPermission) {
            ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_CODE);
        } else {
            Log.i(TAG, "checkPermissions: All required permissions granted");
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                           int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_REQUEST_CODE) {
            boolean allGranted = true;
            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                    allGranted = false;
                    break;
                }
            }

            if (!allGranted) {
                Toast.makeText(this, "Permissions are required to use the app",
                        Toast.LENGTH_LONG).show();
                finish();
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        gameBoard.onDestroy();
        unbindAndStopServices();
        releaseMediaPlayer();
    }


    public void playSound(int cardNum, int cardValue) {
        if (cardNum < 1 || cardNum > 11) {
            return;
        }

        // 停止当前可能正在播放的音频
        stopCurrentPlayback();

        // 保存牌值，用于后续播放
        this.mCardValue = cardValue;

        // 获取张数音频文件的资源ID (z1.mp3 对应 R.raw.z1)
        int numResId = getResourceId("z" + cardNum, "raw",
                this.getApplicationContext().getPackageName());

        if (numResId == 0) {
            Log.e(TAG, "未找到张数音频文件: z" + cardNum + ".mp3");
            return;
        }

        // 播放张数音频
        playAudio(numResId, true);
    }

    private void playAudio(int resId, boolean isFirst) {
        // 释放之前的MediaPlayer实例
        releaseMediaPlayer();

        // 创建新的MediaPlayer实例
        mMediaPlayer = MediaPlayer.create(this.getApplicationContext(), resId);

        if (mMediaPlayer == null) {
            Log.e(TAG, "无法创建MediaPlayer实例，资源ID: " + resId);
            return;
        }

        // 设置播放完成监听器
        mMediaPlayer.setOnCompletionListener(mp -> {
            if (isFirst) {
                // 如果是第一个音频（张数）播放完成，则播放第二个音频（牌值）
                int cardResId = getResourceId("c" + mCardValue, "raw",
                        this.getApplicationContext().getPackageName());
                if (cardResId != 0) {
                    playAudio(cardResId, false);
                } else {
                    Log.e(TAG, "未找到牌值音频文件: c" + mCardValue + ".mp3");
                    releaseMediaPlayer();
                }
            } else {
                // 第二个音频播放完成，释放资源
                releaseMediaPlayer();
            }
        });

        // 设置错误监听器
        mMediaPlayer.setOnErrorListener((mp, what, extra) -> {
            Log.e(TAG, "MediaPlayer错误: what=" + what + ", extra=" + extra);
            releaseMediaPlayer();
            return true;
        });

        // 开始播放
        mMediaPlayer.start();
    }

    private int getResourceId(String name, String type, String packageName) {
        return this.getApplicationContext().getResources().getIdentifier(name, type, packageName);
    }

    private void stopCurrentPlayback() {
        if (mMediaPlayer != null && mMediaPlayer.isPlaying()) {
            mMediaPlayer.stop();
        }
    }

    private void releaseMediaPlayer() {
        if (mMediaPlayer != null) {
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }

}